﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using easyccms.BusinessLayer;
using easyccms.BusinessLayer.Entities;
using easyccms.BusinessLayer.Repositories;
using easyccms.WebUI.Areas.Administrator.Models;
using easyccms.WebUI.Code;
using easyccms.WebUI.Infrastructure;

namespace easyccms.WebUI.Areas.Administrator.Controllers
{
    public class MenuController : Controller, IAdminController
    {
        private IMenuRepository _menuRepository{
            get { return DependencyInjector.Resolve<IMenuRepository>(); }
        }

        private  IUserGroupRepository _userGroupRepository{
            get { return DependencyInjector.Resolve<IUserGroupRepository>(); }
        }

        private UserProvider _userProvider
        {
            get { return new UserProvider(); }
        }

        private IUnitOfWork _unitOfWork{
            get { return DependencyInjector.Resolve<IUnitOfWork>(); }
        }


        //
        // GET: /Administrator/Menu/

        public ActionResult Index()
        {
            MenuListModel menuModel = new MenuListModel {Menus = this._menuRepository.All.Where(x => !x.Deleted)};
            return View(menuModel);
        }

        //
        // GET: /Administrator/Menu/Create

        public ActionResult Create()
        {
            var menuModel = GetMenuModel();
            return View(menuModel);
        }

        //
        // POST: /Administrator/Menu/Create

        [HttpPost]
        public ActionResult Create(Menu menu)
        {
            if (ModelState.IsValid)
            {
                //fetch all about group.
                menu.UserGroup = _userGroupRepository.Load(menu.UserGroup.UserGroupId);
                menu.Created = DateTime.Now;
                menu.User = this._userProvider.GetCurrentUser();
                try
                {
                    this._unitOfWork.StartTransaction();
                    _menuRepository.Save(menu);
                    this._unitOfWork.CommitTransaction();

                    return RedirectToAction("Index");
                }
                catch (Exception)
                {
                    //do default below
                    this._unitOfWork.RollbackTransaction();
                }
            }

            MenuModel menuModel = GetMenuModel();
            menuModel.Menu = menu;
            return View(menuModel);
        }

        //
        // GET: /Administrator/Menu/Edit/5

        public ActionResult Edit(int id)
        {
            MenuModel menuModel = GetMenuModel();
            menuModel.Menu = this._menuRepository.Load(id);
            return View(menuModel);
        }

        //
        // POST: /Administrator/Menu/Edit/

        /// <summary>
        /// Edits the specified menu.
        /// </summary>
        /// <param name="menu">The menu.</param>
        /// <returns>Action for edit menu.</returns>
        [HttpPost]
        public ActionResult Edit(Menu menu)
        {
            Menu menuToUpdate = this._menuRepository.Load(menu.MenuId);
            if (menuToUpdate == null) throw new ArgumentNullException("Menu does not exists in database.");
            menuToUpdate = menu;
            menuToUpdate.UserGroup = _userGroupRepository.Load(menu.UserGroup.UserGroupId);
            menuToUpdate.MenuOrder = 0;
            menuToUpdate.Created = DateTime.Now;
            menuToUpdate.User = this._userProvider.GetCurrentUser();
            if (ModelState.IsValid)
            {
                try
                {
                    this._unitOfWork.StartTransaction();
                    this._menuRepository.Save(menuToUpdate);
                    this._unitOfWork.CommitTransaction();

                    return RedirectToAction("Index");
                }
                catch
                {
                    this._unitOfWork.RollbackTransaction();
                    //do nothing as it is handeled below
                }
            }

            MenuModel menuModel = GetMenuModel();
            menuModel.Menu = menu;
            return View(menuModel);
        }

        //
        // GET: /Administrator/Menu/MoveToBin/5

        /// <summary>
        /// Moves to bin.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult MoveToBin(int id)
        {
            Menu menuToDisplay = this._menuRepository.Load(id);
            if (menuToDisplay == null) throw new ArgumentNullException("Menu does not exists in database.");

            MenuModel menuModel = GetMenuModel();
            menuModel.Menu = menuToDisplay;
            return View(menuModel);
        }

        /// <summary>
        /// Moves to bin.
        /// </summary>
        /// <param name="menu">The menu.</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult MoveToBin(Menu menu)
        {
            Menu menuToUpdate = this._menuRepository.Load(menu.MenuId);
            if (menuToUpdate == null) throw new ArgumentNullException("Menu does not exists in database.");
            menuToUpdate.Deleted = true;

            if (ModelState.IsValid)
            {
                try
                {
                    this._unitOfWork.StartTransaction();
                    this._menuRepository.Save(menuToUpdate);
                    this._unitOfWork.CommitTransaction();

                    return RedirectToAction("Index");
                }
                catch
                {
                    this._unitOfWork.RollbackTransaction();
                    //do nothing as it is handeled below
                }
            }

            MenuModel menuModel = GetMenuModel();
            menuModel.Menu = menu;
            return View(menuModel);
        }

        public ActionResult SetDisplayUntil(DateTime displayUntil, int menuId)
        {
            throw new NotImplementedException();
        }

        public ActionResult Enable(int id)
        {
            throw new NotImplementedException();
        }

        public ActionResult Disable(int id)
        {
            throw new NotImplementedException();
        }

        public ActionResult GetLastChanged(int noOfChanged)
        {
            throw new NotImplementedException();
        }

        public ActionResult Bin()
        {
            MenuListModel menuModel = new MenuListModel { Menus = this._menuRepository.All.Where(x => x.Deleted) };
            return View(menuModel);
        }

        public ActionResult BinDelete(int id)
        {
            TempData["SelectedTab"] = "Menu";
            Menu menuToDelete = this._menuRepository.Load(id);
            if (menuToDelete == null) throw new ArgumentNullException("Menu does not exists in database.");

            if (ModelState.IsValid)
            {
                try
                {
                    this._unitOfWork.StartTransaction();
                    this._menuRepository.Delete(menuToDelete);
                    this._unitOfWork.CommitTransaction();

                    return RedirectToAction("Bin","Management");
                }
                catch
                {
                    this._unitOfWork.RollbackTransaction();
                    //do nothing as it is handeled below
                }
            }

            return RedirectToAction("Bin", "Management");
        }

        public ActionResult BinRestore(int id)
        {
            TempData["SelectedTab"] = "Menu";

              Menu menuToUpdate = this._menuRepository.Load(id);
            if (menuToUpdate == null) throw new ArgumentNullException("Menu does not exists in database.");
            menuToUpdate.Deleted = false;

            if (ModelState.IsValid)
            {
                try
                {
                    this._unitOfWork.StartTransaction();
                    this._menuRepository.Save(menuToUpdate);
                    this._unitOfWork.CommitTransaction();

                    return RedirectToAction("Bin", "Management");
                }
                catch
                {
                    this._unitOfWork.RollbackTransaction();
                    //do nothing as it is handeled below
                }
            }

            return RedirectToAction("Bin", "Management");
        }

        #region private menu helpers

        /// <summary>
        /// Gets the menu model.
        /// </summary>
        /// <returns></returns>
        private MenuModel GetMenuModel()
        {
            List<SelectListItem> listItems =
                this._userGroupRepository.All.AsEnumerable().Select(
                    userGroup =>
                    new SelectListItem() {Text = userGroup.GroupName, Value = userGroup.UserGroupId.ToString()}).
                    ToList();
            List<SelectListItem> menuContainers = new List<SelectListItem>
                                                      {new SelectListItem() {Text = "Default", Value = "Default"}};

            MenuModel menuModel = new MenuModel
                                      {
                                          UserGroups = listItems.AsEnumerable(),
                                          MenuContainers = menuContainers.AsEnumerable()
                                      };
            return menuModel;
        }

        #endregion

    }
}
